package com.wyr.admin.mq.config;

import com.wyr.admin.mq.listener.DynamicQueueListener;
import com.wyr.admin.service.UserInfoService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.AcknowledgeMode;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.amqp.SimpleRabbitListenerContainerFactoryConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;


/**
 * MQ配置
 *
 * @author wangyiren
 * @version 1.0
 * &#064;title RabbitMessagePostProcessor
 * &#064;description
 * &#064;date 2025/03/06 14:37
 */
@Slf4j
@Configuration
public class RabbitMqConfig {

    /**
     * tts topic
     */
    @Value("${zp.tts_topic}")
    private String zpTtsTopic;

    /**
     * 调用记录 topic
     */
    @Value("${zp.invoke_topic}")
    private String invokeTopic;

    /**
     * 翻译队列 topic
     */
    @Value("${zp.translate_topic}")
    private String translateTopic;

    @Autowired
    private UserInfoService userInfoService;

    /**
     * 默认mq连接工厂
     */
    public static final String DEFAULT_CONNECTION_FACTORY = "defaultConnectionFactory";

    /**
     * 默认rabbitmq操作模板
     */
    public static final String DEFAULT_RABBIT_TEMPLATE = "defaultRabbitTemplate";

    /**
     * 默认mq监听器连接工厂
     */
    public static final String DEFAULT_LISTENER_CONNECTION_FACTORY = "defaultListenerConnectionFactory";

    /**
     * 默认mq连接工厂
     *
     * @param host
     * @param port
     * @param username
     * @param password
     * &#064;description
     * @return: org.springframework.amqp.rabbit.connection.ConnectionFactory
     * @author wangyiren
     * &#064;date 2025/4/2 09:28
     */
    @Bean(name = DEFAULT_CONNECTION_FACTORY)
    @Primary
    public ConnectionFactory defaultConnectionFactory(@Value("${rabbit.host}") String host,
                                                      @Value("${rabbit.port}") int port,
                                                      @Value("${rabbit.username}") String username,
                                                      @Value("${rabbit.password}") String password) {
        CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
        connectionFactory.setAddresses(host);
        connectionFactory.setPort(port);
        connectionFactory.setUsername(username);
        connectionFactory.setPassword(password);
        return connectionFactory;
    }

    /**
     * 创建默认mq模板
     *
     * @param connectionFactory
     * &#064;description
     * @return: org.springframework.amqp.rabbit.core.RabbitTemplate
     * @author wangyiren
     * &#064;date 2025/4/1 18:00
     */
    @Bean(name = DEFAULT_RABBIT_TEMPLATE)
    @Primary
    public RabbitTemplate defaultRabbitTemplate(@Qualifier(DEFAULT_CONNECTION_FACTORY) ConnectionFactory connectionFactory) {
        return new RabbitTemplate(connectionFactory);
    }

    /**
     * 默认监听工厂
     *
     * @param configurer
     * @param connectionFactory
     * &#064;description
     * @return: org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory
     * @author wangyiren
     * &#064;date 2025/4/1 18:01
     */
    @Bean(name = DEFAULT_LISTENER_CONNECTION_FACTORY)
    @Primary
    public SimpleRabbitListenerContainerFactory defaultContainerFactory(SimpleRabbitListenerContainerFactoryConfigurer configurer,
                                                                        @Qualifier(DEFAULT_CONNECTION_FACTORY) ConnectionFactory connectionFactory) {
        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
        factory.setAcknowledgeMode(AcknowledgeMode.MANUAL);
//        factory.setMaxConcurrentConsumers(5);
//        factory.setConcurrentConsumers(1);
//        factory.setPrefetchCount(1);
        configurer.configure(factory, connectionFactory);
        return factory;
    }

    /**
     * 管理rabbitMq对象
     *
     * @param connectionFactory
     * &#064;description
     * @return: org.springframework.amqp.rabbit.core.RabbitAdmin
     * @author wangyiren
     * &#064;date 2025/4/1 18:01
     */
    @Bean
    @Primary
    public RabbitAdmin rabbitAdmin(@Qualifier(DEFAULT_CONNECTION_FACTORY) ConnectionFactory connectionFactory) {
        return new RabbitAdmin(connectionFactory);
    }

    /**
     * 声明普通队列 - invokeTopic
     *
     * @param connectionFactory
     * &#064;description
     * @return: java.lang.String
     * @author wangyiren
     * &#064;date 2025/4/2 09:18
     */
    @Bean
    public String invokeTopicQueue(@Qualifier(DEFAULT_CONNECTION_FACTORY) ConnectionFactory connectionFactory) {
        try {
            connectionFactory.createConnection().createChannel(false).queueDeclare(invokeTopic, true, false, false, null);
        } catch (IOException e) {
            log.error("队列声明异常：{}", invokeTopic);
        }
        return invokeTopic;
    }

    /**
     * 声明普通队列 - translateQueue
     *
     * @param connectionFactory
     * &#064;description
     * @return: java.lang.String
     * @author wangyiren
     * &#064;date 2025/4/2 09:18
     */
    @Bean
    public String translateQueue(@Qualifier(DEFAULT_CONNECTION_FACTORY) ConnectionFactory connectionFactory) {
        try {
            connectionFactory.createConnection().createChannel(false).queueDeclare(translateTopic, true, false, false, null);
        } catch (IOException e) {
            log.error("队列声明异常：{}", translateTopic);
        }
        return translateTopic;
    }

    /**
     * 声明-公共的tts队列
     *
     * @param connectionFactory
     * @param rabbitAdmin
     * @param dynamicQueueListener
     * &#064;description
     * @return: java.lang.String
     * @author wangyiren
     * &#064;date 2025/4/2 09:19
     */
    @Bean
    public String zpTtsQueue(@Qualifier(DEFAULT_CONNECTION_FACTORY) ConnectionFactory connectionFactory, @Qualifier("rabbitAdmin") RabbitAdmin rabbitAdmin
            , @Qualifier("dynamicQueueListener") DynamicQueueListener dynamicQueueListener) {
        Map<String, Object> arguments = new HashMap<>(1);
        arguments.put("x-single-active-consumer", true);
        Queue queue = new Queue(zpTtsTopic, true, false, false, arguments);
        // 服务器创建队列
        rabbitAdmin.declareQueue(queue);
        // 创建监听容器
        SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        container.setAfterReceivePostProcessors(new RabbitMessagePostProcessor());
        container.setQueues(queue);
        // 监听器适配器
        container.setMessageListener(dynamicQueueListener);
        container.setAcknowledgeMode(AcknowledgeMode.MANUAL);
        container.setDefaultRequeueRejected(false);

        // 设置并发消费者数量
        container.setConcurrentConsumers(1);
        container.setMaxConcurrentConsumers(1);

        // 启动监听容器
        container.start();

        return zpTtsTopic;
    }

    /**
     * 动态队列监听器bean
     *
     * @return
     */
    @Bean
    public DynamicQueueListener dynamicQueueListener() {
        DynamicQueueListener dynamicQueueListener = new DynamicQueueListener();
        dynamicQueueListener.setUserInfoService(userInfoService);
        return dynamicQueueListener;
    }

}
